import threading

import gevent

import settings
from db_tools.db_handler import DbHandler
from tools.hd_logger import HdLogger
from tools.send_to_ui_tools import send_msg_to_ui, send_order_state_to_ui,send_flagData_state_to_ui


class StateListener(object):
    def __init__(self, plcClient, camera, deviceStates):
        self.db = DbHandler()
        self.logger = HdLogger()
        self.states = deviceStates
        self.camera = camera
        self.loopDuration = 0.5
        self.plcClient = plcClient
        self.managerThread = threading.Thread(target=self.manager, name="managerThread")
        self.plcListenerThread = threading.Thread(target=self.plc_listener,name="plcListenerThread")
        self.cameraListener = threading.Thread(target=self.camera_listener,name="cameraListener")


    def plc_listener(self):
        while settings.IS_MAIN_ALIVE:
            try:
                connectState = self.plcClient.CheckPlcIsOnline()
                if connectState:
                    self.states.plcStates.online = True
                    ret,val = self.plcClient.GetPlcState()
                    if ret == 0:
                        if val == 1:
                            self.states.plcStates.run = "停机中"
                        elif val == 0:
                            self.states.plcStates.run  = "待机中"
                        else:
                            self.states.plcStates.run  = "运行中"
                else:
                    self.states.plcStates.online = False
                    self.plcClient.ConnectionPlc()
                gevent.sleep(1)
            except Exception as e:
                self.states.plcStates.online = False
                errorInfo = "in plc_listener() Error: {}".format(str(e))
                print(errorInfo)
                self.logger.debug(errorInfo)
                gevent.sleep(1)

    def camera_listener(self):
        cameraConnected = True
        while settings.IS_MAIN_ALIVE:
            cameraIsOnline = self.camera.is_device_online()
            if not cameraIsOnline:
                ret = self.reconnect_camera()
                if ret != 0:
                    if cameraConnected:
                        self.logger.debug(ret)
                    cameraConnected = False
                else:
                    cameraIsOnline = True
                    cameraConnected = True
                    self.logger.debug("相机连接成功!")
            self.states.cameraGroupStates = [cameraIsOnline]
            gevent.sleep(1)


    def reconnect_camera(self):
        try:
            ret = self.camera.re_connect_area_camera()
            if ret != 0:
                self.camera.errorMsg = "相机连接失败,原因:{}".format(ret)
                return self.camera.errorMsg
            else:
                return 0
        except Exception as e:
            print("in reconnect_camera() error : {}".format(str(e)))
            return "相机连接失败1,失败原因:{}".format(str(e))

    def web_show_data_initial(self):
        """
        前端界面的一些显示数据的初始化
        :return:
        """
        orderUsedKey = self.db.get_working_used_key()
        msg = {
            "val": orderUsedKey
        }
        # send_settings_state_to_ui()
        send_order_state_to_ui(msg)  # 更新工单的信息
        # 更新workingInfo的数据
        # send_working_info_state_to_ui()

    def manager(self):
        self.updateStatesFlag = False
        while settings.IS_MAIN_ALIVE:
            self.send_device_state_to_ui()
            try:
                if not self.plcListenerThread.is_alive():
                    self.plcListenerThread = threading.Thread(target=self.plc_listener,name="plcListenerThread")
                    self.plcListenerThread.setDaemon(True)
                    self.plcListenerThread.start()

                if not self.cameraListener.is_alive():
                    self.cameraListener = threading.Thread(target=self.camera_listener,name="cameraListener")
                    self.cameraListener.setDaemon(True)
                    self.cameraListener.start()
                if not self.updateStatesFlag:
                    gevent.sleep(3)
                    send_flagData_state_to_ui("flagDataParams")
                    # self.web_show_data_initial()
                    self.db.update_login_state(False)
                    self.updateStatesFlag = True
                gevent.sleep(2)
            except Exception as e:
                errorInfo = "in manager() error:{}".format(str(e))
                print(errorInfo)
                self.logger.debug(errorInfo)
                gevent.sleep(1)
    def send_device_state_to_ui(self):
        msgType = "deviceStates"
        msg = self.states.pack_state_to_dict()
        send_msg_to_ui(msgType, msg)
